import axios from 'axios'

// 添加额外请求头信息
const service = axios.create({
  baseURL: '/',
  // 超时时间
  timeout: 600000,
  withCredentials: true,
  'X-Requested-With': 'XMLHttpRequest',
  'cache-control': 'no-cache',
  Pragma: 'no-cache'
})

// 添加请求拦截器，在请求中添加授权头信息
service.interceptors.request.use(
  (config) => {
    const token = getToken()

    config.headers.Authorization = `Bearer ${token}`
    
    return config
  },
  (err) => {
    return Promise.reject(err)
  }
)

// 添加响应拦截器，截取正常响应结果中的 data.result 或者 data 作为响应主体
service.interceptors.response.use(
  (response) => {
    let result = {}

    // success 方法，一定是正常完成了业务逻辑
    if (response.data.result) {
      result = response.data.result
    } else {
      result = response.data
    }
    return result
  },
  (err) => {
    // 添加统一报错处理
    const { response } = err
    const code = response.status
    const { data } = response

    if (data) {
      const { error } = data
      let message = data.message || data.msg || '未知错误，请联系管理员'

      if (error) {
        message = error.message || data.message

        if (error.validationErrors && error.validationErrors.length > 0) {
          message = error.validationErrors[0].message
        }
      }
      return throwError(code, message, data.code)
    } else {
      if (code) {
        let message = response.message || ''
        return throwError(code, message, response.code)
      } else {
        return Promise.reject(err)
      }
    }
  }
)

const throwError = (code, message, innerCode) => {
  let res = message
  // 发生错误
  switch (code) {
    // 业务错误不直接弹出错误
    case 400:
      if (innerCode && innerCode === '40010') {
        res = {
          code: 40010,
          message: message
        }
      }

      return Promise.reject(res)
    case 404:
      return Promise.reject(message)
    case 403:
    case 422:
    case 415:
    case 406:
      // 返回包含 message 信息的 Promise.reject 对象，在调用接口的错误处理逻辑中展示 reject 中的错误信息
      return Promise.reject(message)
    case 401:
      // 退出登录，并跳转到认证中心授权登录页面
      return signOut()
    case 500:
      // 直接显示给客户查看的信息
      console.error(message)
      return Promise.reject(new Error(message))
    case 502:
      return Promise.reject(new Error('502 Bad Gateway'))
    case 10400:
      // 返回包含 message 信息的 Promise.reject 对象
      // eslint-disable-next-line prefer-promise-reject-errors
      return Promise.reject({
        code: 10440,
        message: message
      })
    default:
      return Promise.reject(message)
  }
}

export default service
